// log setup

#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <string>


#define DEBUG(logger, ...) LOG(logger, debug, __VA_ARGS__)
#define INFO(logger, ...) LOG(logger, info, __VA_ARGS__)
#define WARN(logger, ...) LOG(logger, warn, __VA_ARGS__)
#define ERROR(logger, ...) LOG(logger, err, __VA_ARGS__)
#define FATAL(logger, ...) LOG(logger, critical, __VA_ARGS__)
#define LOG(logger, lv, ...) \
    logger.log(spdlog::source_loc{path_to_filename(__FILE__).c_str(), __LINE__, ""}, spdlog::level::lv, __VA_ARGS__)

inline std::string
path_to_filename(const std::string &path) {
    return path.substr(path.find_last_of("\\/") + 1);
}

inline std::string
get_log_path(const std::string &file_name) {
    std::string path = __FILE__;
    return path.substr(0, path.find_last_of("\\/") + 1) + "log/" + file_name;
}

inline spdlog::logger
setup_log(const std::string &file_name) {
    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
    console_sink->set_level(spdlog::level::debug);
    console_sink->set_pattern("%Y-%m-%d %H:%M:%S.%f [%@] [%^%l%$] - %v");

    auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
            get_log_path(file_name), 1048576 * 20, 3);
    file_sink->set_level(spdlog::level::debug);
    file_sink->set_pattern("%Y-%m-%d %H:%M:%S.%f [%@] [%l] - %v");

    spdlog::logger logger("multi_sink", {console_sink, file_sink});
#ifdef NDEBUG
    logger.set_level(spdlog::level::info);
#else
    logger.set_level(spdlog::level::debug);
#endif
    return logger;
}


int main() {
    auto mylog = setup_log("server.log");
    DEBUG(mylog, "This is DEBUG: {}", 1);
    INFO(mylog, "This is INFO: {}", 1.2);
    WARN(mylog, "This is WARN: {}", "ss");
    ERROR(mylog, "This is ERROR: foo");
    FATAL(mylog, "This is FATAL: bar");
}